using RugbyClubWpf.Helpers;
using RugbyClubWpf.Models;
using RugbyClubWpf.Data;
using RugbyClubWpf.Views;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Linq;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace RugbyClubWpf.ViewModels
{
    /// <summary>
    /// ViewModel for the Coach view.
    /// </summary>
    public class CoachViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// Gets or sets the collection of coaches.
        /// </summary>
        public ObservableCollection<Coach> Coaches { get; set; }

        /// <summary>
        /// Gets or sets the collection of players.
        /// </summary>
        public ObservableCollection<Player> Players { get; set; }

        /// <summary>
        /// Gets or sets the collection of matches.
        /// </summary>
        public ObservableCollection<Match> Matches { get; set; }

        /// <summary>
        /// Gets the command to add a player.
        /// </summary>
        public ICommand AddPlayerCommand { get; }

        /// <summary>
        /// Gets the command to delete a player.
        /// </summary>
        public ICommand DeletePlayerCommand { get; }

        /// <summary>
        /// Gets the command to update a player.
        /// </summary>
        public ICommand UpdatePlayerCommand { get; }

        /// <summary>
        /// Gets the command to add a match.
        /// </summary>
        public ICommand AddMatchCommand { get; }

        /// <summary>
        /// Gets the command to delete a match.
        /// </summary>
        public ICommand DeleteMatchCommand { get; }

        /// <summary>
        /// Gets the command to update a match.
        /// </summary>
        public ICommand UpdateMatchCommand { get; }

        private Player _selectedPlayer;
        /// <summary>
        /// Gets or sets the selected player.
        /// </summary>
        public Player SelectedPlayer
        {
            get => _selectedPlayer;
            set
            {
                _selectedPlayer = value;
                OnPropertyChanged();
            }
        }

        private Match _selectedMatch;
        /// <summary>
        /// Gets or sets the selected match.
        /// </summary>
        public Match SelectedMatch
        {
            get => _selectedMatch;
            set
            {
                _selectedMatch = value;
                OnPropertyChanged();
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CoachViewModel"/> class.
        /// </summary>
        /// <param name="userId">The user ID of the coach.</param>
        public CoachViewModel(int userId)
        {
            using (var context = new RugbyClubContext())
            {
                var coach = context.Coaches.FirstOrDefault(c => c.UserId == userId);
                if (coach != null)
                {
                    Coaches = new ObservableCollection<Coach> { coach };
                    Players = new ObservableCollection<Player>(context.Players.Where(p => p.CoachId == coach.CoachId).ToList());
                    Matches = new ObservableCollection<Match>(context.Matches.Where(m => m.CoachId == coach.CoachId).ToList());
                }
                AddPlayerCommand = new RelayCommand(_ => AddPlayer(coach));
                DeletePlayerCommand = new RelayCommand(_ => DeletePlayer());
                UpdatePlayerCommand = new RelayCommand(_ => UpdatePlayer());
                AddMatchCommand = new RelayCommand(_ => AddMatch(coach));
                DeleteMatchCommand = new RelayCommand(_ => DeleteMatch());
                UpdateMatchCommand = new RelayCommand(_ => UpdateMatch());
            }
        }

        private void AddPlayer(Coach coach)
        {
            var dialog = new AddPlayerDialog
            {
                DataContext = new Player()
            };
            if (dialog.ShowDialog() == true)
            {
                var newPlayer = (Player)dialog.DataContext;
                newPlayer.CoachId = coach.CoachId;
                Players.Add(newPlayer);
                using (var context = new RugbyClubContext())
                {
                    context.Players.Add(newPlayer);
                    context.SaveChanges();
                }
            }
        }

        private void DeletePlayer()
        {
            if (SelectedPlayer == null)
            {
                MessageBox.Show("Please select a player to delete.");
                return;
            }

            using (var context = new RugbyClubContext())
            {
                context.Players.Remove(SelectedPlayer);
                context.SaveChanges();
            }
            Players.Remove(SelectedPlayer);
        }

        private void UpdatePlayer()
        {
            if (SelectedPlayer == null)
            {
                MessageBox.Show("Please select a player to update.");
                return;
            }

            var dialog = new UpdatePlayerDialog
            {
                DataContext = SelectedPlayer
            };
            if (dialog.ShowDialog() == true)
            {
                using (var context = new RugbyClubContext())
                {
                    context.Players.Update(SelectedPlayer);
                    context.SaveChanges();
                }
            }
        }

        private void AddMatch(Coach coach)
        {
            var dialog = new AddMatchDialog
            {
                DataContext = new Match()
            };
            if (dialog.ShowDialog() == true)
            {
                var newMatch = (Match)dialog.DataContext;
                newMatch.CoachId = coach.CoachId;
                Matches.Add(newMatch);
                using (var context = new RugbyClubContext())
                {
                    context.Matches.Add(newMatch);
                    context.SaveChanges();
                }
            }
        }

        private void DeleteMatch()
        {
            if (SelectedMatch == null)
            {
                MessageBox.Show("Please select a match to delete.");
                return;
            }

            using (var context = new RugbyClubContext())
            {
                context.Matches.Remove(SelectedMatch);
                context.SaveChanges();
            }
            Matches.Remove(SelectedMatch);
        }

        private void UpdateMatch()
        {
            if (SelectedMatch == null)
            {
                MessageBox.Show("Please select a match to update.");
                return;
            }

            var dialog = new UpdateMatchDialog
            {
                DataContext = SelectedMatch
            };
            if (dialog.ShowDialog() == true)
            {
                using (var context = new RugbyClubContext())
                {
                    context.Matches.Update(SelectedMatch);
                    context.SaveChanges();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}
